package com.h5ve.toolkit.controller;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.h5ve.base.api.R;
import com.h5ve.base.constant.AppConstants;
import com.h5ve.base.constant.CommonConstants;
import com.h5ve.base.constant.SqlConstants;
import com.h5ve.base.util.StrUtil;
import com.h5ve.log.annotation.SysLog;
import com.h5ve.security.util.SecurityUtil;
import com.h5ve.system.entity.Menu;
import com.h5ve.system.service.MenuService;
import com.h5ve.toolkit.dto.GenDataDto;
import com.h5ve.toolkit.entity.Form;
import com.h5ve.toolkit.entity.PageInfo;
import com.h5ve.toolkit.service.ApplicationService;
import com.h5ve.toolkit.service.FormService;
import com.h5ve.toolkit.service.PageInfoService;
import com.h5ve.toolkit.util.BuilderUtil;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.anyline.data.param.ConfigStore;
import org.anyline.data.param.init.DefaultConfigStore;
import org.anyline.entity.DataRow;
import org.anyline.proxy.ServiceProxy;
import org.anyline.service.AnylineService;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import javax.swing.text.html.parser.Entity;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 页面信息
 *
 * @author Wings
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping(AppConstants.APP_TOOLKIT + "/pageInfo")
public class PageInfoController {

    private final PageInfoService pageInfoService;
    private final FormService formService;
    private final MenuService menuService;
    private final ApplicationService applicationService;
    private final JdbcTemplate jdbcTemplate;

    /**
     * 查询条件构建
     *
     * @param pageInfo
     * @return R
     */
    private LambdaQueryWrapper<PageInfo> getQueryWrapper(PageInfo pageInfo) {
        return new LambdaQueryWrapper<PageInfo>()
                .eq(!StrUtil.isEmptyIfNum(pageInfo.getApplicationId()), PageInfo::getApplicationId, pageInfo.getApplicationId())
                .eq(StrUtil.isNotBlank(pageInfo.getCode()), PageInfo::getCode, pageInfo.getCode())
                .like(StrUtil.isNotBlank(pageInfo.getName()), PageInfo::getName, pageInfo.getName())
                .eq(StrUtil.isNotBlank(pageInfo.getStatus()), PageInfo::getStatus, pageInfo.getStatus());
    }

    /**
     * 页面信息列表
     *
     * @param pageInfo
     * @return R
     */
    @GetMapping("/list")
    public R list(PageInfo pageInfo) {
        List<PageInfo> groupList = pageInfoService.list(getQueryWrapper(pageInfo));
        return R.ok(groupList, groupList.size());
    }

    /**
     * 页面信息
     *
     * @param id 编号
     * @return R
     */
    @GetMapping("/{id}")
    public R getById(@PathVariable("id") Integer id) {
        return R.ok(pageInfoService.getById(id));
    }

    /**
     * 动态表单查询：根据表唯一id
     *
     * @param code 动态表单唯一code编码
     * @return
     */
    @ApiOperation("表单查询-通过编码")
    @GetMapping("/getByCode")
    public R getByCode(@RequestParam String code) {
        if (code == null || "".equals(code)) {
            return R.error("编码不能为空");
        }
        PageInfo pageInfo = pageInfoService.getOne(new QueryWrapper<PageInfo>().eq("code", code).eq("is_main", "1"));
        /*if ("1".equals(pageInfo.getType())) {  // 树表
            Table table = tableService.getOne(new QueryWrapper<Table>().eq("table_name", "form_" + pageInfo.getTableName()));
            if (table != null) {
                if (CharSequenceUtil.isNotBlank(table.getOptions()) && !"{}".equals(table.getOptions())) {
                    JSONObject jsonObject = JSONUtil.parseObj(table.getOptions());
                    pageInfo.setTreeId(jsonObject.getStr("treeId"));
                    pageInfo.setTreeName(jsonObject.getStr("treeName"));
                    pageInfo.setTreeParentId(jsonObject.getStr("treeParentId"));
                }
            }
        } else if ("2".equals(pageInfo.getType())) {  //主子表
            Table table = tableService.getOne(new QueryWrapper<Table>().eq("table_name", "form_" + pageInfo.getTableName()));
            if (table != null) {
                pageInfo.setChildTable(table.getChildTable());
            }
        }*/
        return R.ok(pageInfo);
    }

    /**
     * 页面信息新增
     *
     * @param pageInfo
     * @return R
     */
    @SysLog("页面新增")
    @PostMapping("/save")
    public R save(@RequestBody PageInfo pageInfo) {
        if (pageInfo.getParentId() == null) {
            pageInfo.setParentId(0l);
        }
        pageInfo.setCode(IdWorker.getIdStr().substring(4));
        //pageInfo.setDefinitionId(IdWorker.getIdStr());
        pageInfo.setIsMain("1");
        pageInfoService.save(pageInfo);
        //创建菜单
        if ("0".equals(pageInfo.getType())) {
            BuilderUtil.createMenu(pageInfo.getName(), pageInfo.getApplicationId(), pageInfo.getRemarks());
        } else {
            BuilderUtil.createAllMenu(pageInfo);
        }
        //创建数据表
        if (StrUtil.isNotBlank(pageInfo.getPageData())) {
            BuilderUtil.createTable(pageInfo);
        }
        return R.ok(pageInfo.getId());
    }

    /**
     * 页面信息修改
     *
     * @param pageInfo
     * @return R
     */
    @SneakyThrows
    @SysLog("页面修改")
    @PutMapping("/update")
    public R update(@RequestBody PageInfo pageInfo) {
        /*PageInfo info = null;
        if (0 != pageInfo.getParentId()) {
            info = pageInfoService.getById(pageInfo.getParentId());
        }*/
        pageInfoService.updateById(pageInfo);
        //更新用户页面名称
        //创建菜单
        if ("0".equals(pageInfo.getType())) {
            BuilderUtil.createMenu(pageInfo.getName(), pageInfo.getApplicationId(), pageInfo.getRemarks());
        } else {
            BuilderUtil.createAllMenu(pageInfo);
        }
        //创建数据表
        if (StrUtil.isNotBlank(pageInfo.getPageData())) {
            BuilderUtil.createTable(pageInfo);
        }
        return R.ok();
    }

    /**
     * 新增表单数据验证
     * ————验证表单名称是否重复
     * ————验证数据库表名是否重复
     *
     * @param str
     * @return
     */
    @PostMapping("/checkName")
    public R checkName(@RequestBody String str) {
        if (StrUtil.isNotBlank(str)) {
            List<PageInfo> pageInfos = pageInfoService.list(new LambdaQueryWrapper<PageInfo>().eq(PageInfo::getName, str).eq(PageInfo::getIsMain, "1"));
            if (pageInfos != null && pageInfos.size() > 0) {
                if (str.equals(pageInfos.get(0).getName())) {
                    return R.error("表单名称已存在请重新输入！");
                }
            }
        }
        return R.ok();
    }

    /**
     * 页面信息删除
     *
     * @param id
     * @return R
     */
    @SysLog("页面删除")
    @DeleteMapping("/remove/{id}")
    public R remove(@PathVariable("id") Integer id) {
        if (pageInfoService.list(new QueryWrapper<PageInfo>().eq("parent_id", id)).size() > 0) {
            return R.error("存在下级页面,不允许删除");
        }
        if (formService.list(new QueryWrapper<Form>().eq("group_id", id)).size() > 0) {
            return R.error("存在关联表单,不允许删除");
        }
        pageInfoService.removeById(id);
        return R.ok();
    }

    /**
     * 页面状态更改
     *
     * @param pageInfo
     * @return R
     */
    @SysLog("页面状态更改")
    @GetMapping("/changeStatus")
    public R changeStatus(PageInfo pageInfo) {
        pageInfoService.updateById(pageInfo);
        return R.ok();
    }

    /**
     * 加载页面列表树
     */
    @GetMapping("/pageTree")
    public R pageTree(PageInfo pageInfo) {
        List<PageInfo> pageList = pageInfoService.list(new LambdaQueryWrapper<PageInfo>().eq(!StrUtil.isEmptyIfNum(pageInfo.getApplicationId()), PageInfo::getApplicationId, pageInfo.getApplicationId()).orderByAsc(PageInfo::getSort));
        PageInfo pageInfo1 = new PageInfo();
        pageInfo1.setId(0l);
        pageInfo1.setParentId(-1l);
        pageInfo1.setName("根目录");
        pageList.add(0, pageInfo1);
        //查询顶级菜单编号
        String menuId = "1";
        Menu menu = menuService.getOne(new LambdaQueryWrapper<Menu>().eq(Menu::getName, pageInfo.getName()).eq(Menu::getApplicationId, pageInfo.getApplicationId()).last("limit 1"));
        if (menu != null) {
            menuId = menu.getId() + "";
        }
        return R.ok(pageList).setMsg(menuId);
    }

    /**
     * 获取菜单树
     *
     * @return
     */
    @ApiOperation("获取菜单树")
    @GetMapping("/getMenuTree")
    public R getMenuTree() {
        List<Map<String, Object>> list = jdbcTemplate.queryForList(SqlConstants.MENU_TREE);
        return R.ok(list);
    }

    @RequestMapping(value = "/genList")
    public R genList(@RequestParam("code") String code, @RequestParam("params") String params, Page<Entity> page) {
        PageInfo pageInfo = pageInfoService.getOne(new LambdaQueryWrapper<PageInfo>().eq(PageInfo::getCode, code).eq(PageInfo::getIsMain, "1"));
        if (pageInfo == null) {
            return R.error("页面信息不存在");
        }
        ConfigStore configs = new DefaultConfigStore();
        configs.page(page.getCurrent(), (int) page.getSize()).total(true);
        //configs.and();
        List<Map<String, Object>> mapList = ServiceProxy.service().maps(CommonConstants.SQLPREFIX + pageInfo.getTableName(), configs);
        return R.ok(mapList).setTotal(configs.getPageNavi().getTotalRow());
    }

    /**
     * 动态表单查询：根据表唯一id
     *
     * @param code 动态表单唯一code编码
     * @return
     */
    @ApiOperation("表单查询-通过编码")
    @GetMapping("/genByCode")
    public R genByCode(@RequestParam String code, @RequestParam String id) {
        PageInfo pageInfo = pageInfoService.getOne(new QueryWrapper<PageInfo>().eq("code", code).eq("is_main", "1"));
        if (pageInfo == null) {
            return R.error("页面信息不存在");
        }

        return R.ok(ServiceProxy.service().query(CommonConstants.SQLPREFIX + pageInfo.getTableName(), "id", id));
    }

    /**
     * 保存数据表单
     */
    @SneakyThrows
    @PostMapping("genSave")
    public R genSave(@RequestBody GenDataDto genDataDto) {
        PageInfo pageInfo = pageInfoService.getOne(new LambdaQueryWrapper<PageInfo>().eq(PageInfo::getCode, genDataDto.getCode()).eq(PageInfo::getIsMain, "1"));
        if (pageInfo == null) {
            return R.error("页面信息不存在");
        }

        DataRow jData = JSONUtil.toBean(genDataDto.getData(), DataRow.class);
        //JSONObject jData = JSONUtil.parseObj(genDataDto.getData());
        List<String> columns = new ArrayList<>();
        JSONObject columnList = JSONUtil.parseObj(pageInfo.getPageData());
        JSONArray jsonArray = columnList.getJSONArray("list");
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject columnObj = jsonArray.getJSONObject(i);
            columns.add(columnObj.getStr("model"));
        }
        AnylineService service = ServiceProxy.service();
        if (jData.get("id") != null && !StrUtil.isEmptyIfNum(jData.getLong("id"))) {
            jData.set("update_by", SecurityUtil.getUserName());
            jData.set("update_time", new Date());
            columns.add("update_by");
            columns.add("update_time");
            service.update(CommonConstants.SQLPREFIX + pageInfo.getTableName(), jData, columns.toArray(new String[columns.size()]));
        } else {
            jData.set("dept_id", SecurityUtil.getDeptId());
            jData.set("create_by", SecurityUtil.getUserName());
            jData.set("create_time", new Date());
            columns.add("dept_id");
            columns.add("create_by");
            columns.add("create_time");
            service.insert(CommonConstants.SQLPREFIX + pageInfo.getTableName(), jData, columns);
        }
        return R.ok("保存数据成功");
    }

    /**
     * 批量删除数据表单
     */
    @DeleteMapping("genDel")
    public R executeDelete(String code, String ids) throws SQLException {
        PageInfo pageInfo = pageInfoService.getOne(new LambdaQueryWrapper<PageInfo>().eq(PageInfo::getCode, code).eq(PageInfo::getIsMain, "1"));
        if (pageInfo == null) {
            return R.error("页面信息不存在");
        }
        ServiceProxy.service().deletes(CommonConstants.SQLPREFIX + pageInfo.getTableName(), "id", ids.split(","));
        return R.ok("删除数据成功");
    }
}
